-module(util).
-compile([export_all]).

lines([$\r|Rest], Lines, Current) ->
    lines(Rest, Lines, Current);

lines([$\n|Rest], Lines, Current) ->
    lines(Rest, [Current|Lines], "");

lines([X|Rest], Lines, Current) ->
    lines(Rest, Lines, Current ++ [X]);

lines([], Lines, []) -> lists:reverse(Lines);
lines([], Lines, Current) -> lists:reverse([Current|Lines]).

lines(Str) -> lines(Str, [], "").

die() ->
    % without sleep last io:format may not be written
    receive after 10 -> ok end,
    erlang:halt().

die(X) ->
    receive after 10 -> ok end,
    erlang:halt(X).


intpow(Base, N) when is_number(N), N >= 0 -> 
    intpow(Base, N, 1).

intpow(_Base, 0, Result) -> Result;
intpow(Base, N, Result) when is_number(N), N >= 1 -> 
    intpow(Base, N-1, Base * Result).

pow2(Power) -> intpow(2, Power).

min({signed, Bits}) -> -pow2(Bits - 1);
min({unsigned, _Bits}) -> 0.
max({signed, Bits}) -> pow2(Bits - 1) - 1;
max({unsigned, Bits}) -> pow2(Bits) - 1.

inttypes() -> [{signed, 8},
               {unsigned, 8},
               {signed, 16},
               {unsigned, 16},
               {signed, 32},
               {unsigned, 32},
               {signed, 64},
               {unsigned, 64}].

pr(Text) when is_list(Text) ->
    io:format(Text ++ "\n"),
    receive after 1 -> ok end;

pr(Term) -> pr("~p", [Term]).

pr(Text, Args) ->
    io:format(Text ++ "\n", Args),
    receive after 1 -> ok end.
